import { defineComponent, h } from "@vue/runtime-core";
import { isReactive, isRef, isProxy, ref } from "@vue/reactivity";
import Modules from "./modules";
interface layoutConfig {
  id?: string;
  name: string;
  props?: any;
  childs?: any;
}
export default defineComponent({
  props: {
    config: {} as any,
    comps: {} as any,
  },
  setup(props) {
    const Comps = {
      // 挂载基础模块
      ...Modules,
      // 挂载附加模块
      ...props.comps,
    };
    console.log("当前挂载的组件：", Comps);
    function renderRef(data: any) {
      // console.log(data);
      if (typeof data._value === "object") return JSON.stringify(data.value);
      return data.value;
    }
    function renderReactive(data: any) {
      return JSON.stringify(data);
    }
    function loadProps(props: any) {
      const obj: any = {};
      Object.keys(props).forEach((key) => {
        isRef(props[key])
          ? (obj[key] = props[key].value)
          : (obj[key] = props[key]);
      });
      return obj;
    }
    // const renderCache: any = {};
    const render = (config: layoutConfig) => {
      const { name, props, childs } = config;

      function loadComp(name: any, props: any, childs: any) {
        const comp = Comps[name];
        return (
          comp &&
          (childs
            ? h(
                comp,
                loadProps(props),
                ((childs) => {
                  // 有子元素时
                  const children: any = {};
                  Object.keys(childs).forEach((key: string) => {
                    const childComp = childs[key];
                    if (Array.isArray(childComp)) {
                      // console.log("Loading ", childComp);
                      children[key] = () =>
                        childComp.map((child: any) => {
                          if (typeof child === "string") return child;
                          else if (isRef(child)) return renderRef(child);
                          else if (!isProxy(child) && isReactive(child))
                            return renderReactive(child);
                          else return render(child);
                        });
                    } else if (typeof childComp === "string") {
                      children[key] = childComp;
                    }
                  });
                  return children;
                })(childs)
              )
            : h(comp, loadProps(props)))
        );
      }

      // 尝试缓存id优化，但是导致原生组件无法刷新
      // if (id) {
      //   if (renderCache[id]) {
      //     // console.log(id, renderCache[id]);
      //     return renderCache[id]
      //   } else {
      //     renderCache[id] = loadComp(name, props, childs);
      //     return renderCache[id]
      //   }
      // }

      const out = loadComp(name, props, childs);

      // console.log(out);
      return out || `组件“${name}”加载失败`;
    };
    return () => [render(props.config)]; 
  },
});
